﻿// -------------------------------------------------------------------------
//    @FileName         :    NFCProxyClientModule.cpp
//    @Author           :    Gao.Yi
//    @Date             :   2022-09-18
//    @Email			:    445267987@qq.com
//    @Module           :    NFCProxyClientModule
//
// -------------------------------------------------------------------------

#include "NFProxyPlayerModule.h"

#include <iomanip>
#include <cryptopp/integer.h>

#include "proto_access2zone.nanopb.h"
#include "NFServerComm/NFServerCommon/NFIServerMessageModule.h"
#if NF_PLATFORM == NF_PLATFORM_WIN
#else
#include <netinet/in.h>
#endif
#include <NFLogicCommon/CustomPacketParse.h>

#include "NFProxySession.h"
#include "NFLogicCommon/NFLogicCommon.h"
#include "NFServerComm/NFServerCommon/NFIProxyServerModule.h"
#include "NFLogicCommon/NFLogicBindRpcService.h"

NFCProxyPlayerModule::NFCProxyPlayerModule(NFIPluginManager* p) : NFMMODynamicModule(p)
{
}

NFCProxyPlayerModule::~NFCProxyPlayerModule()
{
}

int NFCProxyPlayerModule::Awake()
{
    NFServerConfig* pConfig = FindModule<NFIConfigModule>()->GetAppConfig(NF_ST_PROXY_SERVER);
    if (pConfig)
    {
        int iRetCode = FindModule<NFIMessageModule>()->ResetPacketParse(pConfig->ParseType, new CustomPacketParse());
        CHECK_RET(iRetCode, "ResetPacketParse Failed");
    }

    ////////////////////////////////////////////////////////////////////////////////////////////////////////////
    //////来自客户端的协议////////////////////////////////////////
    RegisterClientMessage(NF_ST_PROXY_SERVER, proto_client2access::Proto_C2ACmd::E_C2A_AUTH_SYN, true);
    RegisterClientMessage(NF_ST_PROXY_SERVER, proto_client2access::Proto_C2ACmd::E_C2A_AUTH_ACK, true);
    RegisterClientMessage(NF_ST_PROXY_SERVER, proto_client2access::Proto_C2ACmd::E_C2A_TRANSFERDATA);
    RegisterServerMessage(NF_ST_PROXY_SERVER, proto_ff::E_ACCESS2ZONE_STOP);
    RegisterServerMessage(NF_ST_PROXY_SERVER, proto_ff::E_ACCESS2ZONE_TRANSFER);
    RegisterServerMessage(NF_ST_PROXY_SERVER, proto_ff::E_ACCESS2ZONE_BROADCAST);
    RegisterServerMessage(NF_ST_PROXY_SERVER, proto_ff::E_ACCESS2ZONE_MULTICAST);
    RegisterServerMessage(NF_ST_PROXY_SERVER, proto_ff::E_ZONE2ACCESS_SETROUTING, true);

    /////////来自Login Server返回的协议//////////////////////////////////////////////////
    /////来自World Server返回的协议////////////////////////////////////////
    //FindModule<NFIMessageModule>()->AddRpcService<proto_ff::NOTIFY_GATE_LEAVE_GAME>(NF_ST_PROXY_SERVER, this,
    //                                                                                          &NFCProxyPlayerModule::OnRpcServicePlayerLeaveGame);
    return 0;
}

int NFCProxyPlayerModule::Init()
{
    NFServerConfig* pConfig = FindModule<NFIConfigModule>()->GetAppConfig(NF_ST_PROXY_SERVER);
    if (pConfig)
    {
        uint64_t proxyClientLinkId = FindModule<NFIMessageModule>()->GetClientLinkId(NF_ST_PROXY_SERVER);
        if (proxyClientLinkId > 0)
        {
            /*
            注册服务器事件
            */
            FindModule<NFIMessageModule>()->AddEventCallBack(NF_ST_PROXY_SERVER, proxyClientLinkId, this, &NFCProxyPlayerModule::OnProxyClientSocketEvent);
            FindModule<NFIMessageModule>()->AddOtherCallBack(NF_ST_PROXY_SERVER, proxyClientLinkId, this, &NFCProxyPlayerModule::OnHandleProxyClientOtherMessage);
        }
        else
        {
            NFLogInfo(NF_LOG_DEFAULT, 0, "Get NF_ST_PROXY_SERVER ClientLinkId Failed!");
            return -1;
        }

        uint64_t proxyClienUdptLinkId = FindModule<NFIMessageModule>()->GetClientUdpLinkId(NF_ST_PROXY_SERVER);
        if (proxyClienUdptLinkId > 0)
        {
            /*
            注册服务器事件
            */
            FindModule<NFIMessageModule>()->AddEventCallBack(NF_ST_PROXY_SERVER, proxyClienUdptLinkId, this, &NFCProxyPlayerModule::OnProxyClientSocketEvent);
            FindModule<NFIMessageModule>()->AddOtherCallBack(NF_ST_PROXY_SERVER, proxyClienUdptLinkId, this, &NFCProxyPlayerModule::OnHandleProxyClientOtherMessage);
        }
        else
        {
            NFLogInfo(NF_LOG_DEFAULT, 0, "Get NF_ST_PROXY_SERVER GetClientUdpLinkId Failed!");
            return -1;
        }

        uint64_t proxyServerLinkId = FindModule<NFIMessageModule>()->GetServerLinkId(NF_ST_PROXY_SERVER);
        if (proxyServerLinkId > 0)
        {
            /*
            注册服务器事件
            */
            FindModule<NFIMessageModule>()->AddOtherCallBack(NF_ST_PROXY_SERVER, proxyServerLinkId, this, &NFCProxyPlayerModule::OnHandleOtherServerToClientMsg);
        }
        else
        {
            NFLogInfo(NF_LOG_DEFAULT, 0, "Get NF_ST_PROXY_SERVER ClientLinkId Failed!");
            return -1;
        }
    }
    else
    {
        NFLogError(NF_LOG_DEFAULT, 0, "I Can't get the Proxy Server config!");
        return -1;
    }

    return 0;
}

int NFCProxyPlayerModule::Tick()
{
    return 0;
}

int NFCProxyPlayerModule::OnDynamicPlugin()
{
    return 0;
}

int NFCProxyPlayerModule::OnTimer(uint32_t nTimerId)
{
    return 0;
}

int NFCProxyPlayerModule::OnHandleClientMessage(uint64_t unLinkId, NFDataPackage& packet)
{
    if (!m_pObjPluginManager->IsInited(NF_ST_PROXY_SERVER))
    {
        NFLogError(NF_LOG_DEFAULT, packet.nParam1, "Proxy Server not inited, drop client msg:{}", packet.ToString());
        return -1;
    }

    if (m_pObjPluginManager->IsServerStopping())
    {
        NFLogError(NF_LOG_DEFAULT, packet.nParam1, "Proxy Server is Stopping, drop client msg:{}", packet.ToString());
        return -1;
    }

    switch (packet.nMsgId)
    {
        case proto_client2access::Proto_C2ACmd::E_C2A_AUTH_SYN:
        {
            OnHandleAuthSyn(unLinkId, packet);
            break;
        }
        case proto_client2access::Proto_C2ACmd::E_C2A_AUTH_ACK:
        {
            OnHandleAuthAck(unLinkId, packet);
            break;
        }
        case proto_client2access::Proto_C2ACmd::E_C2A_TRANSFERDATA:
        {
            OnHandleTransferToServer(unLinkId, packet);
            break;
        }
        default:
        {
            NFLogError(NF_LOG_DEFAULT, 0, "Client MsgId:{} Register, But Not Handle, Package:{}", packet.nMsgId, packet.ToString());
            break;
        }
    }
    return 0;
}


int NFCProxyPlayerModule::OnHandleServerMessage(uint64_t unLinkId, NFDataPackage& packet)
{
    if (!m_pObjPluginManager->IsInited(NF_ST_PROXY_SERVER))
    {
        NFLogError(NF_LOG_DEFAULT, packet.nParam1, "World Server not inited, drop client msg:{}", packet.ToString());
        return -1;
    }

    if (m_pObjPluginManager->IsServerStopping())
    {
        NFLogError(NF_LOG_DEFAULT, packet.nParam1, "World Server is Stopping, drop client msg:{}", packet.ToString());
        return -1;
    }

    switch (packet.nMsgId)
    {
        case E_ACCESS2ZONE_STOP:
        {
            OnHandleSessionStop(unLinkId, packet);
            break;
        }
        case E_ACCESS2ZONE_TRANSFER:
        {
            OnHandleTransferToClient(unLinkId, packet);
            break;
        }
        case E_ACCESS2ZONE_MULTICAST:
        {
            OnHandleMultiCastToClient(unLinkId, packet);
            break;
        }
        case E_ACCESS2ZONE_BROADCAST:
        {
            OnHandleBroadCastToClient(unLinkId, packet);
            break;
        }
        case proto_ff::E_ZONE2ACCESS_SETROUTING:
        {
            OnHandleSetRouting(unLinkId, packet);
            break;
        }
        default:
        {
            NFLogError(NF_LOG_DEFAULT, 0, "Server MsgId:{} Register, But Not Handle, Package:{}", packet.nMsgId, packet.ToString());
            break;
        }
    }
    return 0;
}

/*
	处理客户端链接事件
*/
int NFCProxyPlayerModule::OnProxyClientSocketEvent(eMsgType nEvent, uint64_t unLinkId)
{
    NFLogTrace(NF_LOG_DEFAULT, 0, "--- begin -- ");
    if (nEvent == eMsgType_CONNECTED)
    {
        std::string ip = FindModule<NFIMessageModule>()->GetLinkIp(unLinkId);
        uint32_t port = FindModule<NFIMessageModule>()->GetPort(unLinkId);
        NFLogDebug(NF_LOG_DEFAULT, 0, "client ip:{} port:{} linkId:{} connected proxy server success!", ip, port, unLinkId);
    }
    else if (nEvent == eMsgType_DISCONNECTED)
    {
        std::string ip = FindModule<NFIMessageModule>()->GetLinkIp(unLinkId);
        uint32_t port = FindModule<NFIMessageModule>()->GetPort(unLinkId);
        NFLogInfo(NF_LOG_DEFAULT, 0, "client ip:{} port:{} link:{} disconnected proxy server!", ip, port, unLinkId);
        OnHandleClientDisconnect(unLinkId);
    }
    NFLogTrace(NF_LOG_DEFAULT, 0, "--- end -- ");
    return 0;
}

/*
	处理客户端未注册协议
*/
int NFCProxyPlayerModule::OnHandleProxyClientOtherMessage(uint64_t unLinkId, NFDataPackage& packet)
{
    auto pSession = m_proxySessionMap.GetElement(unLinkId);
    CHECK_EXPR(pSession, -1, "can't find the session:{}", unLinkId);
    CHECK_EXPR(pSession->m_bInit, -1, "session not init:{}", unLinkId);

    uint32_t msgId = packet.nMsgId;

    NFServerConfig* pConfig = FindModule<NFIConfigModule>()->GetAppConfig(NF_ST_PROXY_SERVER);
    NF_ASSERT(pConfig);

    FindModule<NFIServerMessageModule>()->SendProxyMsgByBusId(NF_ST_PROXY_SERVER, pSession->m_dstBusId, NF_MODULE_CLIENT, msgId, packet.GetBuffer(), packet.GetSize(), unLinkId, packet.nMsgSeq);
    return 0;
}

int NFCProxyPlayerModule::OnHandleClientDisconnect(uint64_t unLinkId)
{
    auto pSession = m_proxySessionMap.GetElement(unLinkId);
    if (pSession)
    {
        NFServerConfig* pConfig = FindModule<NFIConfigModule>()->GetAppConfig(NF_ST_PROXY_SERVER);
        NF_ASSERT(pConfig);
        proto_ff::Access2ZoneStop stop;
        stop.set_m_sessionobjid(pSession->m_sessionId);

        FindModule<NFIServerMessageModule>()->SendProxyMsgByBusId(NF_ST_PROXY_SERVER, pSession->m_dstBusId, E_ACCESS2ZONE_STOP, stop, pConfig->GetBusId(), unLinkId);
        m_proxySessionMap.RemoveElement(unLinkId);
        pSession = nullptr;
        NFLogDebug(NF_LOG_DEFAULT, unLinkId, "delete session by unlinkId:{} from m_proxySessionMap", unLinkId);
    }
    return 0;
}

int NFCProxyPlayerModule::OnHandleOtherServerToClientMsg(uint64_t unLinkId, NFDataPackage& packet)
{
    return 0;
}

int NFCProxyPlayerModule::OnHandleRedirectMsg(uint64_t unLinkId, NFDataPackage& packet)
{
    return 0;
}

int NFCProxyPlayerModule::OnHandleAuthSyn(uint64_t unLinkId, NFDataPackage& packet)
{
    proto_client2access::C2A_AuthSyn oAuthSync;
    CLIENT_MSG_PROCESS_WITH_PRINTF(packet, oAuthSync);
    NFServerConfig* pConfig = FindModule<NFIConfigModule>()->GetAppConfig(NF_ST_PROXY_SERVER);
    NF_ASSERT(pConfig);

    uint32_t dstBusId = NFServerIDUtil::GetBusID(pConfig->RouteConfig.RouteAgent);
    int routeServerType = pConfig->RouteConfig.RouteServerType;
    std::string ip = FindModule<NFIMessageModule>()->GetLinkIp(unLinkId);

    auto pSession = m_proxySessionMap.GetElement(unLinkId);
    if (pSession)
    {
        NFLogError(NF_LOG_DEFAULT, unLinkId, "nLinkId:{} exist..........", unLinkId);
        FindModule<NFIMessageModule>()->CloseLinkId(unLinkId);
        return 0;
    }

    if (dstBusId == 0)
    {
        uint64_t uin = (uint64_t)NFHash::BKDRHash(oAuthSync.account_info().data(), oAuthSync.account_info().size());
        auto pDstServer = FindModule<NFIMessageModule>()->GetSuitServerByServerType(NF_ST_PROXY_SERVER, (NF_SERVER_TYPE)routeServerType, uin);
        if (pDstServer)
        {
            dstBusId = pDstServer->GetBusId();
        }
    }

    proto_ff::Access2ZoneQueryUinReq queryUinReq;
    queryUinReq.set_m_accountinfo(oAuthSync.account_info());
    queryUinReq.set_m_token(oAuthSync.token());
    queryUinReq.set_m_playerip(ip);
    proto_ff::Access2ZoneQueryUinRes queryUnRes;
    int iRetCode = FindModule<NFIMessageModule>()->GetRpcService<proto_ff::E_ACCESS2ZONE_QUERYUINREQ>(NF_ST_PROXY_SERVER, (NF_SERVER_TYPE)routeServerType, dstBusId, queryUinReq, queryUnRes, pConfig->GetBusId(), unLinkId);
    if (iRetCode != 0 || queryUnRes.m_ret() != 0)
    {
        NFLogError(NF_LOG_DEFAULT, unLinkId, "nLinkId:{} GetRpcService E_ACCESS2ZONE_QUERYUINREQ Failed..........", unLinkId);
        FindModule<NFIMessageModule>()->CloseLinkId(unLinkId);
        return 0;
    }

    pSession = std::make_shared<NFProxySession>();
    pSession->m_strClientPublicKey = oAuthSync.dhpubkey_client();
    pSession->m_accountInfo = oAuthSync.account_info();
    pSession->m_uin = queryUnRes.m_uin();
    pSession->m_dstBusId = dstBusId;

    NFLogDebug(NF_LOG_DEFAULT, unLinkId, "session AuthSyn ok, unlinkId:{} uin:{}", unLinkId, pSession->m_uin);

    proto_client2access::A2C_AuthSynAck oAuthSynAck;
    oAuthSynAck.set_dhpubkey_server(pSession->m_client_dh_pubKey->BytePtr(), pSession->m_client_dh_pubKey->SizeInBytes());
    oAuthSynAck.set_encrypt(static_cast<proto_client2access::Proto_C2AEncryptType>(pConfig->EncryptConfig.EncryptPolicy));
    oAuthSynAck.set_compress(static_cast<proto_client2access::Proto_C2ACompressType>(pConfig->EncryptConfig.CompressPolicy));
    oAuthSynAck.set_player_uin(queryUnRes.m_uin());

    FindModule<NFIMessageModule>()->Send(unLinkId, proto_client2access::E_A2C_AUTH_SYNACK, oAuthSynAck);
    m_proxySessionMap.AddElement(unLinkId, pSession);
    return 0;
}

int NFCProxyPlayerModule::OnHandleAuthAck(uint64_t unLinkId, NFDataPackage& packet)
{
    proto_client2access::C2A_AuthAck oAuthAck;
    CLIENT_MSG_PROCESS_WITH_PRINTF(packet, oAuthAck);

    NFServerConfig* pConfig = FindModule<NFIConfigModule>()->GetAppConfig(NF_ST_PROXY_SERVER);
    NF_ASSERT(pConfig);

    int routeServerType = pConfig->RouteConfig.RouteServerType;

    std::string ip = FindModule<NFIMessageModule>()->GetLinkIp(unLinkId);

    auto pSession = m_proxySessionMap.GetElement(unLinkId);
    if (pSession == nullptr)
    {
        NFLogError(NF_LOG_DEFAULT, unLinkId, "nLinkId:{} not exist..........", unLinkId);
        FindModule<NFIMessageModule>()->CloseLinkId(unLinkId);
        return 0;
    }

    bool ret = pSession->init_aes(pSession->m_strClientPublicKey.data(), pSession->m_strClientPublicKey.size());
    if (!ret)
    {
        NFLogError(NF_LOG_DEFAULT, unLinkId, "nLinkId:{} init_aes failed", unLinkId);
        FindModule<NFIMessageModule>()->CloseLinkId(unLinkId);
        return 0;
    }

    std::string cipherText;
    pSession->aes_decrypt(oAuthAck.plain_text(), cipherText);
    if (cipherText != oAuthAck.cipher_text())
    {
        NFLogError(NF_LOG_DEFAULT, unLinkId, "nLinkId:{} aes_decrypt failed, plain_text:{} cipher_text:{} new cipher_text:{}", unLinkId, oAuthAck.plain_text(), oAuthAck.cipher_text(), cipherText);
        FindModule<NFIMessageModule>()->CloseLinkId(unLinkId);
        return 0;
    }

    proto_ff::Access2ZoneStart startReq;
    startReq.set_m_playerip(ip);
    startReq.set_m_accountinfo(pSession->m_accountInfo);
    startReq.set_m_uin(pSession->m_uin);
    proto_ff::Access2ZoneStartRes startRes;
    int iRetCode = FindModule<NFIMessageModule>()->GetRpcService<proto_ff::E_ACCESS2ZONE_START>(NF_ST_PROXY_SERVER, (NF_SERVER_TYPE)routeServerType, pSession->m_dstBusId, startReq, startRes, pConfig->GetBusId(), unLinkId);
    if (iRetCode != 0 || startRes.m_ret() != 0)
    {
        NFLogError(NF_LOG_DEFAULT, 0, "nLinkId:{} GetRpcService E_ACCESS2ZONE_START Failed..........", unLinkId);
        FindModule<NFIMessageModule>()->CloseLinkId(unLinkId);
        return 0;
    }

    pSession = m_proxySessionMap.GetElement(unLinkId);
    if (pSession == nullptr)
    {
        NFLogError(NF_LOG_DEFAULT, unLinkId, "nLinkId:{} session not exist", unLinkId);
        FindModule<NFIMessageModule>()->CloseLinkId(unLinkId);
        return 0;
    }

    pSession->m_sessionId = startRes.m_sessionobjid();
    pSession->m_bInit = true;
    NFLogDebug(NF_LOG_DEFAULT, unLinkId, "session AuthAck ok, unlinkId:{} uin:{}", unLinkId, pSession->m_uin);

    FindModule<NFIMessageModule>()->Send(unLinkId, proto_client2access::E_A2C_STARTOK, "");
    return 0;
}

int NFCProxyPlayerModule::OnHandleTransferToServer(uint64_t unLinkId, NFDataPackage& packet)
{
    auto pSession = m_proxySessionMap.GetElement(unLinkId);
    if (pSession == nullptr)
    {
        NFLogError(NF_LOG_DEFAULT, unLinkId, "nLinkId:{} not exist..........", unLinkId);
        FindModule<NFIMessageModule>()->CloseLinkId(unLinkId);
        return 0;
    }

    if (pSession->m_bInit == false)
    {
        NFLogError(NF_LOG_DEFAULT, unLinkId, "nLinkId:{} not inited..........", unLinkId);
        FindModule<NFIMessageModule>()->CloseLinkId(unLinkId);
        return 0;
    }

    const char* outData = packet.GetBuffer();
    int outLen = packet.GetSize();

    if (outLen < static_cast<int>(sizeof(CSC2SPkgHead)))
    {
        NFLogError(NF_LOG_DEFAULT, unLinkId, "outLen:{} < sizeof(CSC2SPkgHead):{}", outLen, sizeof(CSC2SPkgHead));
        return -1;
    }

    CSC2SPkgHead& stPkgHead = *((CSC2SPkgHead*)outData);
    stPkgHead.m_wDataLen = ntohs(stPkgHead.m_wDataLen);
    stPkgHead.m_wCmd = ntohs(stPkgHead.m_wCmd);
    stPkgHead.m_wSeq = ntohs(stPkgHead.m_wSeq);

    if (outLen != static_cast<int32_t>(stPkgHead.m_wDataLen) + static_cast<int32_t>(sizeof(CSC2SPkgHead)))
    {
        NFLogError(NF_LOG_DEFAULT, unLinkId, "outLen:{} != (int32_t)stPkgHead.m_wDataLen:{} + (int32_t)sizeof(CSC2SPkgHead):{}", outLen, stPkgHead.m_wDataLen, sizeof(CSC2SPkgHead));
        return -1;
    }

    outData = outData + sizeof(CSC2SPkgHead);
    outLen = outLen - sizeof(CSC2SPkgHead);

    NFrame::Proto_FramePkg pkg;
    pkg.set_module_id(packet.mModuleId);
    pkg.set_msg_id(stPkgHead.m_wCmd);
    pkg.set_msg_data(outData, outLen);
    auto pDispInfo = pkg.mutable_disp_info();
    pDispInfo->set_seq(stPkgHead.m_wSeq);

    LOGSVR_TRACE_IF(stPkgHead.m_wCmd != 6, "proxy recv msg:" << stPkgHead.m_wCmd << " seq:" << stPkgHead.m_wSeq);

    FindModule<NFIServerMessageModule>()->SendProxyMsgByBusId(NF_ST_PROXY_SERVER, pSession->m_dstBusId, E_ACCESS2ZONE_TRANSFER, pkg, pSession->m_sessionId);

    return 0;
}

int NFCProxyPlayerModule::OnHandleSessionStop(uint64_t unLinkId, NFDataPackage& packet)
{
    uint64_t clientId = packet.nParam1;
    auto pSession = m_proxySessionMap.GetElement(clientId);
    if (pSession)
    {
        FindModule<NFIMessageModule>()->CloseLinkId(clientId);
    }

    NFLogWarning(NF_LOG_DEFAULT, clientId, "Logic Server Close Client clientId:{}", clientId);

    return 0;
}

int NFCProxyPlayerModule::OnHandleTransferToClient(uint64_t, NFDataPackage& packet)
{
    uint64_t clientId = packet.nParam1;
    uint64_t sessionObjId = packet.nParam2;

    auto pSession = m_proxySessionMap.GetElement(clientId);
    if (pSession == nullptr)
    {
        NFLogError(NF_LOG_DEFAULT, clientId, "nLinkId:{} objId:{} not exist..........", clientId, sessionObjId);
        return 0;
    }

    if (pSession->m_sessionId != sessionObjId)
    {
        FindModule<NFIMessageModule>()->CloseLinkId(clientId);
        CHECK_EXPR(pSession->m_sessionId == sessionObjId, -1, "pSession->m_sessionId:{} != sessionObjId:{}", pSession->m_sessionId, sessionObjId);
    }

    NFrame::Proto_FramePkg pkg;
    CLIENT_MSG_PROCESS_WITH_PRINTF(packet, pkg);

    CSS2CPkgHead appHead;
    appHead.m_iDataLen = htonl(pkg.msg_data().size());
    appHead.m_wCmd = htons(static_cast<uint16_t>(pkg.msg_id()));
    appHead.m_wSeq = htons(static_cast<uint16_t>(pkg.disp_info().seq()));
    appHead.m_wReqSeq = htons(static_cast<uint16_t>(pkg.disp_info().req_seq()));

    m_sendBuffer.Clear();
    m_sendBuffer.PushData(&appHead, sizeof(appHead));
    m_sendBuffer.PushData(pkg.msg_data().data(), pkg.msg_data().size());

    //NFLogTrace(NF_LOG_DEFAULT, 0, "m_iDataLen:{}({}) m_wCmd:{}({}) m_wSeq:{} m_wReqSeq:{}", appHead.m_iDataLen, pkg.msg_data().size(), appHead.m_wCmd, pkg.msg_id(), appHead.m_wSeq, appHead.m_wReqSeq);

    FindModule<NFIMessageModule>()->Send(clientId, proto_client2access::E_A2C_TRANSFERDATA, m_sendBuffer.ReadAddr(), static_cast<uint32_t>(m_sendBuffer.ReadableSize()));
    return 0;
}

int NFCProxyPlayerModule::OnHandleMultiCastToClient(uint64_t unLinkId, NFDataPackage& packet)
{
    NFrame::Proto_FramePkg pkg;
    CLIENT_MSG_PROCESS_WITH_PRINTF(packet, pkg);

    for (int i = 0; i < pkg.redirect_info().id_size(); i++)
    {
        uint64_t clientId = pkg.redirect_info().id(i);
        auto pSession = m_proxySessionMap.GetElement(clientId);
        if (pSession == nullptr)
        {
            NFLogError(NF_LOG_DEFAULT, clientId, "nLinkId:{} not exist..........", clientId);
            continue;
        }

        CSS2CPkgHead appHead;
        appHead.m_iDataLen = htonl(pkg.msg_data().size());
        appHead.m_wCmd = htons(static_cast<uint16_t>(pkg.msg_id()));
        appHead.m_wSeq = htons(static_cast<uint16_t>(pkg.disp_info().seq()));
        appHead.m_wReqSeq = htons(static_cast<uint16_t>(pkg.disp_info().req_seq()));

        m_sendBuffer.Clear();
        m_sendBuffer.PushData(&appHead, sizeof(appHead));
        m_sendBuffer.PushData(pkg.msg_data().data(), pkg.msg_data().size());

        FindModule<NFIMessageModule>()->Send(clientId, proto_client2access::E_A2C_TRANSFERDATA, m_sendBuffer.ReadAddr(), static_cast<uint32_t>(m_sendBuffer.ReadableSize()));
    }

    return 0;
}

int NFCProxyPlayerModule::OnHandleBroadCastToClient(uint64_t unLinkId, NFDataPackage& packet)
{
    NFrame::Proto_FramePkg pkg;
    CLIENT_MSG_PROCESS_WITH_PRINTF(packet, pkg);

    for (auto iter = m_proxySessionMap.Begin(); iter != m_proxySessionMap.End(); ++iter)
    {
        uint64_t clientId = iter->first;
        auto pSession = iter->second;
        if (pSession == nullptr) continue;

        if (pSession->m_dstBusId != packet.nSrcId) continue;

        CSS2CPkgHead appHead;
        appHead.m_iDataLen = htonl(pkg.msg_data().size());
        appHead.m_wCmd = htons(static_cast<uint16_t>(pkg.msg_id()));
        appHead.m_wSeq = htons(static_cast<uint16_t>(pkg.disp_info().seq()));
        appHead.m_wReqSeq = htons(static_cast<uint16_t>(pkg.disp_info().req_seq()));

        m_sendBuffer.Clear();
        m_sendBuffer.PushData(&appHead, sizeof(appHead));
        m_sendBuffer.PushData(pkg.msg_data().data(), pkg.msg_data().size());

        FindModule<NFIMessageModule>()->Send(clientId, proto_client2access::E_A2C_TRANSFERDATA, m_sendBuffer.ReadAddr(), static_cast<uint32_t>(m_sendBuffer.ReadableSize()));
    }
    return 0;
}

int NFCProxyPlayerModule::OnHandleSetRouting(uint64_t unLinkId, NFDataPackage& packet)
{
    proto_ff::Zone2AccessSetRouting pkg;
    CLIENT_MSG_PROCESS_WITH_PRINTF(packet, pkg);

    int iMirrorSessionId = pkg.m_sessionobjid();
    int iTargetSvrId = pkg.m_targetsvrid();
    int iTransId = pkg.m_transid();

    uint64_t clientId = packet.nParam1;
    uint64_t sessionObjId = packet.nParam2;

    NFServerConfig* pConfig = FindModule<NFIConfigModule>()->GetAppConfig(NF_ST_PROXY_SERVER);
    NF_ASSERT(pConfig);

    int routeServerType = pConfig->RouteConfig.RouteServerType;

    int iRetCode = 0;
    do
    {
        auto pSession = m_proxySessionMap.GetElement(clientId);
        if (pSession == nullptr)
        {
            NFLogError(NF_LOG_DEFAULT, clientId, "nLinkId:{} objId:{} not exist..........", clientId, sessionObjId);
            iRetCode = -1;
            break;
        }

        if (pSession->m_sessionId != sessionObjId || pSession->m_sessionId == iMirrorSessionId)
        {
            FindModule<NFIMessageModule>()->CloseLinkId(clientId);
            LOG_ERR(0, -1, "pSession->m_sessionId:{} != sessionObjId:{}", pSession->m_sessionId, sessionObjId);
            iRetCode = -1;
            break;
        }

        if (pSession->m_bInit == false)
        {
            NFLogError(NF_LOG_DEFAULT, unLinkId, "nLinkId:{} not inited..........", unLinkId);
            FindModule<NFIMessageModule>()->CloseLinkId(unLinkId);
            iRetCode = -1;
            break;
        }

        if (pSession->m_dstBusId != packet.nSrcId || pSession->m_dstBusId == iTargetSvrId)
        {
            LOG_ERR(0, -1, "pSession->m_logicBusId:{} == iTargetSvrId:{}", pSession->m_dstBusId, iTargetSvrId);
            FindModule<NFIMessageModule>()->CloseLinkId(unLinkId);
            iRetCode = -1;
            break;
        }

        auto pTargetServer = FindModule<NFIMessageModule>()->GetServerByServerId(NF_ST_PROXY_SERVER, iTargetSvrId);
        if (pTargetServer == nullptr)
        {
            LOG_ERR(0, -1, "iTargetSvrId:{} not exist..........", iTargetSvrId);
            FindModule<NFIMessageModule>()->CloseLinkId(unLinkId);
            iRetCode = -1;
            break;
        }

        pSession->m_sessionId = iMirrorSessionId;
        pSession->m_dstBusId = iTargetSvrId;

        proto_ff::Access2ZoneSetRoutingRpcReq req;
        req.set_m_sessionobjid(iMirrorSessionId);
        proto_ff::Zone2AccessSetRoutingRpcRsp rsp;
        iRetCode = FindModule<NFIMessageModule>()->GetRpcService<proto_ff::E_ZONE2ACCESS_SETROUTING>(NF_ST_PROXY_SERVER, (NF_SERVER_TYPE)routeServerType, pSession->m_dstBusId, req, rsp, pConfig->GetBusId(), clientId);
        if (iRetCode != 0 || rsp.result() != 0)
        {
            LOG_ERR(0, -1, "nLinkId:{} GetRpcService E_ZONE2ACCESS_SETROUTING Failed..........", unLinkId);
            FindModule<NFIMessageModule>()->CloseLinkId(unLinkId);
            break;
        }
    } while (false);

    proto_ff::AccessZone2SetRouting rsp;
    rsp.set_result(iRetCode);
    FindModule<NFIServerMessageModule>()->SendProxyTransMsgByBusId(NF_ST_PROXY_SERVER, packet.nSrcId, proto_ff::E_ZONE2ACCESS_SETROUTING, rsp, 0, iTransId);
    return 0;
}
